/* ###################################### */
/* ###     Util Engine, by Kalith    ### */
/* ###################################### */
/*                                        */

#include "Var.h"

namespace Util
{
    const s_type& Var::VALUE_NONE    = typeid(void);
    const s_type& Var::VALUE_INT     = typeid(Int);
    const s_type& Var::VALUE_UINT    = typeid(UInt);
    const s_type& Var::VALUE_FLOAT   = typeid(Float);
    const s_type& Var::VALUE_DOUBLE  = typeid(Double);
    const s_type& Var::VALUE_BOOL    = typeid(Bool);
    const s_type& Var::VALUE_STRING  = typeid(Str);
    const s_type& Var::VALUE_POINTER = typeid(void*);


    Var::Var() : pValue_(NULL)
    {
    }

    Var::Var(const Var& mVar) : pValue_(mVar.pValue_ ? mVar.pValue_->Clone() : NULL)
    {
    }

    Var& Var::operator = (const Var& mVar)
    {
        if (&mVar != this)
        {
            Var mTemp(mVar);
            Swap(mTemp);
        }
        return *this;
    }

    Bool Var::operator == (const Var& mVar) const
    {
        if (GetType() == mVar.GetType())
        {
            if (IsOfType<Str>())
            {
                Str s1 = Get<Str>();
                Str s2 = mVar.Get<Str>();
                return s1 == s2;
            }
            else if (IsOfType<Float>())
            {
                Float f1 = Get<Float>();
                Float f2 = mVar.Get<Float>();
                return f1 == f2;
            }
            else if (IsOfType<Double>())
            {
                Double d1 = Get<Double>();
                Double d2 = mVar.Get<Double>();
                return d1 == d2;
            }
            else if (IsOfType<Int>())
            {
                Int i1 = Get<Int>();
                Int i2 = mVar.Get<Int>();
                return i1 == i2;
            }
            else if (IsOfType<UInt>())
            {
                UInt ui1 = Get<UInt>();
                UInt ui2 = mVar.Get<UInt>();
                return ui1 == ui2;
            }
            else if (IsOfType<Bool>())
            {
                Bool b1 = Get<Bool>();
                Bool b2 = mVar.Get<Bool>();
                return b1 == b2;
            }
            else if (IsOfType<void>())
                return true;
        }

        return false;
    }

    Bool Var::operator != (const Var& mVar)
    {
        return !(operator == (mVar));
    }

    void Var::Swap(Var& mVar)
    {
        std::swap(pValue_, mVar.pValue_);
    }

    Bool Var::IsEmpty() const
    {
        return (pValue_ == NULL);
    }


    const s_type& Var::GetType() const
    {
        if (pValue_)
        {
            return pValue_->GetType();
        }
        else
        {
            return typeid(void);
        }
    }

    Str Var::ToString() const
    {
        const s_type& mType = GetType();
        if (mType == VALUE_INT) return Str::Convert(Get<Int>());
        else if (mType == VALUE_UINT) return Str::Convert(Get<UInt>())+"u";
        else if (mType == VALUE_FLOAT) return Str::Convert(Get<Float>())+"f";
        else if (mType == VALUE_DOUBLE) return Str::Convert(Get<Double>());
        else if (mType == VALUE_BOOL) return Str::Convert(Get<Bool>());
        else if (mType == VALUE_STRING) return "\""+Get<Str>()+"\"";
        else if (mType == VALUE_POINTER) return Str::Convert(Ptr<void>(Get<void*>()));
        else return "<none>";
    }
}
